From 797b3bd1b11167b100add40e5f5b5f5815ab85f8 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 5 Aug 2020 18:05:46 +0100 Subject: [PATCH] a11y: Do not notify of empty state changes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If the ATContext state hasn't changed—for instance, if the accessible attributes have been set to their default value, or have been set to the same value—do not emit an accessible state change. State changes can be arbitrarily expensive, so we want to ensure that they are meaningful. --- gtk/gtkatcontext.c | 37 +++++++++++++++++++++++++++++++------ gtk/gtkatcontextprivate.h | 4 ++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index 9cdbd0e9f3..e1e2edd599 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -425,6 +425,12 @@ gtk_at_context_update (GtkATContext *self) { g_return_if_fail (GTK_IS_AT_CONTEXT (self)); + /* There's no point in notifying of state changes if there weren't any */ + if (self->updated_properties == 0 && + self->updated_relations == 0 && + self->updated_states == 0) + return; + GtkAccessibleStateChange changed_states = gtk_accessible_attribute_set_get_changed (self->states); GtkAccessiblePropertyChange changed_properties = @@ -435,6 +441,10 @@ gtk_at_context_update (GtkATContext *self) g_signal_emit (self, obj_signals[STATE_CHANGE], 0, changed_states, changed_properties, changed_relations, self->states, self->properties, self->relations); + + self->updated_properties = 0; + self->updated_relations = 0; + self->updated_states = 0; } /*< private > @@ -457,10 +467,15 @@ gtk_at_context_set_accessible_state (GtkATContext *self, { g_return_if_fail (GTK_IS_AT_CONTEXT (self)); + gboolean res = FALSE; + if (value != NULL) - gtk_accessible_attribute_set_add (self->states, state, value); + res = gtk_accessible_attribute_set_add (self->states, state, value); else - gtk_accessible_attribute_set_remove (self->states, state); + res = gtk_accessible_attribute_set_remove (self->states, state); + + if (res) + self->updated_states |= (1 << state); } /*< private > @@ -519,10 +534,15 @@ gtk_at_context_set_accessible_property (GtkATContext *self, { g_return_if_fail (GTK_IS_AT_CONTEXT (self)); + gboolean res = FALSE; + if (value != NULL) - gtk_accessible_attribute_set_add (self->properties, property, value); + res = gtk_accessible_attribute_set_add (self->properties, property, value); else - gtk_accessible_attribute_set_remove (self->properties, property); + res = gtk_accessible_attribute_set_remove (self->properties, property); + + if (res) + self->updated_properties |= (1 << property); } /*< private > @@ -581,10 +601,15 @@ gtk_at_context_set_accessible_relation (GtkATContext *self, { g_return_if_fail (GTK_IS_AT_CONTEXT (self)); + gboolean res = FALSE; + if (value != NULL) - gtk_accessible_attribute_set_add (self->relations, relation, value); + res = gtk_accessible_attribute_set_add (self->relations, relation, value); else - gtk_accessible_attribute_set_remove (self->relations, relation); + res = gtk_accessible_attribute_set_remove (self->relations, relation); + + if (res) + self->updated_relations |= (1 << relation); } /*< private > diff --git a/gtk/gtkatcontextprivate.h b/gtk/gtkatcontextprivate.h index 2ac85bde2d..2b916187fd 100644 --- a/gtk/gtkatcontextprivate.h +++ b/gtk/gtkatcontextprivate.h @@ -90,6 +90,10 @@ struct _GtkATContext GtkAccessibleAttributeSet *states; GtkAccessibleAttributeSet *properties; GtkAccessibleAttributeSet *relations; + + GtkAccessibleStateChange updated_states; + GtkAccessiblePropertyChange updated_properties; + GtkAccessibleRelationChange updated_relations; }; struct _GtkATContextClass -- 2.30.2